#include <iostream>
#include "gtest/gtest.h"
#include "sqlist.h"

TEST(Sqlist, base1)
{
    Sqlist l;
    initList(l);
    insertElem(l, 0, 3);
    insertElem(l, 1, 5);
    insertElem(l, 0, 8);
    ASSERT_EQ(l.length, 3);
    ASSERT_EQ(l.data[0], 8);
    ASSERT_EQ(l.data[1], 3);
    ASSERT_EQ(l.data[2], 5);
    int e;
    int ret = deleteElem(l, 1, e);
    ASSERT_EQ(ret, 1);
    ASSERT_EQ(e, 3);
    ASSERT_EQ(l.data[0], 8);
    ASSERT_EQ(l.data[1], 5);
    ASSERT_EQ(l.length, 2);

    getElem(l, 1, e);
    ASSERT_EQ(e, 5);
    insertElem(l, 0, 10);
    insertElem(l, 0, 11);
    insertElem(l, 0, 12);
    insertElem(l, 0, 13);
    showList(l);
    reserve(l, 0, l.length -1);
    showList(l);
}

TEST(LIST, partition)
{
    Sqlist l;
    initList(l);
    insertElem(l, 0, 3);
    insertElem(l, 1, 4);
    insertElem(l, 2, 2);
    insertElem(l, 3, 1);
    insertElem(l, 4, 7);
    insertElem(l, 5, 8);
    insertElem(l, 6, 2);
    insertElem(l, 7, 3);
    insertElem(l, 8, -1);
    showList(l);
    int index;
    partition(l, index);
    showList(l);
    std::cout << "index:" << index << std::endl;

}

TEST(LIST, deleteDup)
{
    Sqlist l;
    initList(l);
    insertElem(l, 0, 1);
    insertElem(l, 1, 1);
    insertElem(l, 2, 2);
    insertElem(l, 3, 3);
    insertElem(l, 4, 3);
    insertElem(l, 5, 3);
    insertElem(l, 6, 4);
    insertElem(l, 7, 4);
    insertElem(l, 8, 7);
    insertElem(l, 9, 7);
    insertElem(l, 10, 7);
    insertElem(l, 11, 9);
    insertElem(l, 12, 9);
    insertElem(l, 13, 9);
    showList(l);
    deleteDup(l);
    showList(l);





}


TEST(LIST, exercise_41_1_4)
{
    Sqlist l;
    initList(l);
    insertElem(l, 0, 0);
    insertElem(l, 1, 1);
    insertElem(l, 2, 2);
    insertElem(l, 3, 3);
    insertElem(l, 4, 4);
    insertElem(l, 5, 5);
    insertElem(l, 6, 6);
    showList(l);

    exercise_41_1_4(l, 0, 2);
    showList(l);
    exercise_41_1_4(l, 1, 2);
    showList(l);


}

TEST(LNode, create)
{
    int a[] = {1,2};
    LNode *c;
    createListR(c, a, sizeof(a)/sizeof(int));
    ASSERT_EQ(c->next->data, 1);
    ASSERT_EQ(c->next->next->data, 2);
    ASSERT_TRUE(c->next->next->next ==  NULL);
    showLNode(c);
}

TEST(LNode, merge)
{
    int a[] = {1,5,7,14, 246};
    int b[] = {2,4,8,89,102,246};
    LNode *c;
    createListR(c, a, sizeof(a)/sizeof(int));
    LNode *d;
    createListR(d,  b, sizeof(b)/sizeof(int));
    LNode *r, *p;
    mergeToHighLow(c, d, r);
    showLNode(r);
    p = r->next;

    int i = 1;
    while (p != NULL && p->next != NULL)
    {
        ASSERT_TRUE(p->data >= p->next->data);
        p = p->next;
        i++;
    }
    ASSERT_EQ(i, (sizeof(a) + sizeof(b))/sizeof(int));

}

TEST(LNode, exercise_41_1_7)
{
    int a[] = {5,41,7,2,14, 246,6};
    LNode *c;
    createListR(c, a, sizeof(a)/sizeof(int));
    int e;
    showLNode(c);
    exercise_41_1_7(c, e);
    ASSERT_EQ(e, 2);
    showLNode(c);
    exercise_41_1_7(c, e);
    ASSERT_EQ(e, 5);
    showLNode(c);
    exercise_41_1_7(c, e);
    ASSERT_EQ(e, 6);
    showLNode(c);

}

TEST(LNode, exercise_41_1_8)
{
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
    LNode *c;
    createListR(c, a, sizeof(a)/sizeof(int));
    showLNode(c);
    exercise_41_1_8(c);
    showLNode(c);
    free(c);
    int b[] = {1};
    createListR(c, b, sizeof(b)/sizeof(int));
    showLNode(c);
    exercise_41_1_8(c);
    showLNode(c);

    int b1[] = {};
    createListR(c, b1, sizeof(b1)/sizeof(int));
    showLNode(c);
    exercise_41_1_8(c);
    showLNode(c);

}

TEST(LNode, exercise_41_1_9)
{
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    LNode *c, *la, *lb;
    createListR(c, a, sizeof(a) / sizeof(int));
    showLNode(c);
    exercise_41_1_9(la, lb, c);
    showLNode(la);
    showLNode(lb);
}


TEST(LIST, exercise_41_2_1)
{
    Sqlist l;
    initList(l);
    insertElem(l, 0, 3);
    insertElem(l, 1, 2);
    insertElem(l, 2, 7);
    insertElem(l, 3, 4);
    int e = exercise_41_2_1(l);
    ASSERT_EQ(e, 2);
    deleteElem(l, 1, e);
    e = exercise_41_2_1(l);
    ASSERT_EQ(e, 3);
}
int main(int argc,char *argv[])
{
    testing::InitGoogleTest(&argc, argv);//将命令行参数传递给gtest
    return RUN_ALL_TESTS();   //RUN_ALL_TESTS()运行所有测试案例
}